package top.purity.server.user.feign.output.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.crypto.SecureUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import top.purity.framework.common.exception.ServiceException;
import top.purity.server.user.domain.cache.UserCache;
import top.purity.server.user.domain.RoleMenu;
import top.purity.server.user.domain.User;
import top.purity.server.user.domain.UserRole;
import top.purity.server.user.domain.repository.RoleMenuRepository;
import top.purity.server.user.domain.repository.UserRepository;
import top.purity.server.user.domain.repository.UserRoleRepository;
import top.purity.server.user.feign.input.TenantFeign;
import top.purity.server.user.feign.input.dto.TenantInfoDTO;
import top.purity.server.user.feign.output.UserFeign;
import top.purity.server.user.feign.output.dto.AddUserDTO;
import top.purity.server.user.feign.output.dto.LoginDTO;
import top.purity.server.user.feign.output.dto.PermissionDTO;
import top.purity.server.user.service.convert.AccountConvert;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@RestController
@RequiredArgsConstructor
@Slf4j
public class UserFeignImpl implements UserFeign {

    private final UserRepository userRepository;

    private final RoleMenuRepository roleMenuRepository;

    private final UserRoleRepository userRoleRepository;

    private final TenantFeign tenantFeign;

    private final UserCache userCache;

    private static final String KEY = "80c2b40db25240ce92ee04dfe64c91f7";

    @Override
    public LoginDTO getByUsername(String username, String tenantCode) throws ServiceException {
        TenantInfoDTO tenantInfoDTO = tenantFeign.getByCode(tenantCode);
        if (ObjUtil.isEmpty(tenantInfoDTO)) {
            throw new ServiceException("错误的租户编号");
        }

        User user = userRepository.getUserByUsernameAndTenantId(username, tenantInfoDTO.getId().toString());
        return AccountConvert.INSTANCE.convertToLoginDto(user);
    }

    @Override
    public List<PermissionDTO> getPermission(Long userId, Long tenantId) {
        Collection<UserRole> userRoles = userRoleRepository.getUserRolesByAccountIdAndTenantId(userId, tenantId.toString());

        if (CollUtil.isEmpty(userRoles)) {
            return null;
        }

        Set<Long> roleIds = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toSet());
        Collection<RoleMenu> roleMenus = roleMenuRepository.getRoleMenusByRoleIdInAndTenantId(roleIds, tenantId.toString());

        if (CollUtil.isEmpty(roleMenus)) {
            return null;
        }

        Set<Long> menuIds = roleMenus.stream().map(RoleMenu::getMenuId).collect(Collectors.toSet());
        List<PermissionDTO> menuListByIds = tenantFeign.getMenuListByIds(menuIds);
        return menuListByIds;
    }

    @Override
    public Boolean isRootAdmin(Long userId, Long tenantId) throws ServiceException {
        User user = userCache.getUserInfoByIdAndTenantId(userId, tenantId);
        if (ObjUtil.isNull(user)) {
            throw new ServiceException("不存在的用户");
        }
        return user.getRootAdmin();
    }

    @Override
    public void addUserByAddTenant(AddUserDTO dto) {
        User user = AccountConvert.INSTANCE.convertToDo(dto);
        // 进行一次md5加密
        String s = SecureUtil.md5(user.getPassword());
        String s1 = SecureUtil.md5(s);
        String ciphertext = SaSecureUtil.aesEncrypt(KEY, s1);
        user.setPassword(ciphertext);
        user.setTenantId(dto.getTenantId().toString());
        user.setNickName("超级管理员");
        user.setRootAdmin(true);
        userRepository.save(user);
    }
}
